/* 二分图
* 1.二分图、不存在奇数环、染色法不存在矛盾
* 2.匈牙利算法，匹配、最大匹配、匹配点、增广路径
* 3.最小点覆盖、最大独立集、最小路径点覆盖(最小路径重复点覆盖)
    最大匹配数 = 最小点覆盖 = 总点数-最大独立集 = 总点数-最小路径覆盖

* 概念:
    匹配/匹配边: 与其他边没有公共节点的一条边, 我们称这条边为一个匹配/匹配边.
    匹配点: 匹配边上的点
    非匹配点: 不在匹配边上的点
    非匹配边: 图中两点之间的边不是匹配边的边
    最大匹配(匹配边数量的最大值): 最多连多少条边, 使得所有的边无公共点
    增广路(径): 一边的非匹配点到另一边的非匹配点的一条非匹配边和匹配边交替经过的路径. 
    由一个未匹配的顶点开始，经过若干个匹配顶点，最后到达对面集合的一个未匹配顶点的路径，即这条路径将两个不同集合的两个未匹配顶点通过一系列匹配顶点相连。

* 证明:在二分图中最小点覆盖=最大匹配数
    1.证明要想覆盖所有边的点数>=最大匹配数m
    所有的匹配边,相互之间没有公共点(没有交点),而点覆盖是一定要覆盖所有的边,当然也得
    覆盖这些匹配边.但由于这些匹配边没有公共点,所以m个匹配边最少也得需要m个点来覆盖它们
    所以>=m成立

    2.证明要想覆盖所有边的点数=最大匹配数m可以成立
    构造出这种情况,方案如下:
    明确目的:构造出一种方案恰好取了m个点,且这m个点能够将所有的边覆盖掉
    构造方式:
    (1)求出最大匹配,有m个匹配边
    (2)从左边每个非匹配点出发,做一遍增广路径,将路径上的所有点标记
    Notes:这里增广路径一定不会成功,因为成功的话就不是最大匹配了,最大匹配后没有增广路径
    (3)选出左边所有未被标记的点+右边所有被标记的点

* 本题: 
    a[i]=0 || b[i]=0时可以跳过
    一个任务i可以被A、B机器的两种状态a[i]、b[i]完成，将一个任务看成一条边，两种状态看成两个端点，
    要完成一个任务就要从这两个点中选一个点(任务可以在A上执行也可以在B上执行)，
    对于所有任务就要从N+M-2个点中(不包含初始0状态)选出最少的点，覆盖所有的边(任务)，
    问题就变成求最小点覆盖问题(二分图中最小点覆盖等价于最大匹配数--匈牙利算法)。
*/

#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include<iostream>
#include<cstring>
#include<algorithm>
// #define ONLINE_GUDGE
using namespace std;
using PII = pair<int, int>;
#define x first 
#define y second 
const int N = 110, INF = 0x3f3f3f3f;
const int dx[4] = {-1,  0,  1,  0}, 
          dy[4] = { 0,  1,  0, -1};

int n, m, k;
bool g[N][N], st[N];
int match[N];


bool find(int x)
{
    for(int i = 0; i < m; i++)
        if(!st[i] && g[x][i])
        {
            st[i] = true;
            int t = match[i];
            if(t == 0 || find(t))
            {
                match[i] = x;
                return true;
            }
        }
    return false; // 当前节点不可分配对象
}

int main()
{

    #ifdef ONLINE_JUDGE

    #else
    freopen("./in.txt","r",stdin);
    #endif
    ios::sync_with_stdio(false);   
	cin.tie(0);
    
    while(cin >> n, n)
    {
        cin >> m >> k;

        memset(match, 0, sizeof match);
        memset(g, 0, sizeof g);

        while(k--)
        {
            int t, a, b; cin >> t >> a >> b;
            if(!a || !b) continue;
            g[a][b] = true;
        }

        int res = 0;
        for(int i = 1; i < n; i++)
        {
            memset(st, 0, sizeof st);
            if(find(i)) res++;
        }
        cout << res << endl;
    }

    
    return 0;
}